package com.jake.rabbit.sap.aspect;

import com.jake.rabbit.sap.service.ConcurrentQueueService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Queue;

@Aspect
@Component
@Slf4j
public class ConcurrentQueueAspect {

    @Autowired
    private ConcurrentQueueService concurrentQueueService;

    @Autowired
    @Qualifier(value = "sapConcurrentQueue")
    private Queue<LocalDateTime> sapConcurrentQueue;

    @Pointcut("execution(public java.util.Map<String, Object> com.jake.rabbit.sap.service.AttendanceService.*(..))")
    public void handleQueue() {
    }

    @Around(value = "handleQueue()")
    public Object add(ProceedingJoinPoint pjp) {
        boolean notFull = sapConcurrentQueue.offer(LocalDateTime.now());
        log.info("sapConcurrentQueue's size is {}", sapConcurrentQueue.size());
        Object result = null;
        if (notFull) {
            try {
                result = pjp.proceed();
            } catch (Throwable throwable) {
                log.error("{} happens when proceed", throwable.getMessage());
            }
        } else {
            log.error("SAP 已达到最大负载");
        }
        if (result == null) {
            log.warn("the sapConcurrentQueue may be full, the size = " + sapConcurrentQueue.size());
        }
        return result;
    }

    @AfterReturning(pointcut = "handleQueue()")
    public void release() {
        concurrentQueueService.releaseEarliest();
    }

}
